home *** CD-ROM | disk | FTP | other *** search
/ Mastering Computers 3 / Mastering Computers Vol 3.iso / Win95 / Fun&Utils / MFCMSG.EXE / TRACEMSG.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-01  |  15.4 KB  |  602 lines

  1. ////////////////////////////////////////////////////////////////
  2. // TRACEMSG Copyright 1995 Microsoft Systems Journal. 
  3. // If this program works, it was written by Paul DiLascia.
  4. // If not, I don't know who wrote it.
  5. //
  6. // TRACEMSG implements message tracing for MFC CCmdTarget and CWnd classes.
  7. // CMsgTracer does the work. It's called from the template classes generated
  8. // by the definitions in TRACEMSG.H.
  9. //
  10. #include "stdafx.h"
  11. #ifdef   _DEBUG            // the whole file!
  12. #include "tracemsg.h"      // message tracing templates
  13. #include "resource.h"      // command IDs
  14. #include <dde.h>           // for DDE messages
  15.  
  16. IMPLEMENT_DYNAMIC(CMsgTracer, CCmdTarget)
  17.  
  18. BEGIN_MESSAGE_MAP(CMsgTracer, CCmdTarget)
  19.    ON_COMMAND(ID_TRACE_MSG, OnTraceMsg)
  20.    ON_COMMAND(ID_TRACE_CMD, OnTraceCmd)
  21.    ON_UPDATE_COMMAND_UI(ID_TRACE_MSG, OnUpdateTraceMsg)
  22.    ON_UPDATE_COMMAND_UI(ID_TRACE_CMD, OnUpdateTraceCmd)
  23. END_MESSAGE_MAP()
  24.  
  25. CMsgTracer theTracer;      // one and only
  26.  
  27. ////////////////
  28. // Maps ID (WM_ message or ID_ command) to name
  29. //
  30. struct MAPID {
  31.    UINT    nID;            // ID_ or WM_ value
  32.    LPCSTR  lpszName;       // name
  33. };
  34.  
  35. #define MSG(WM_FOO)     { WM_FOO, #WM_FOO },
  36. #define MFCMSG(WM_FOO)  { WM_FOO, "MFC:"#WM_FOO }, // for MFC message
  37. #define APPMSG(WM_FOO)  { WM_FOO, "APP:"#WM_FOO }, // for App message
  38.  
  39. // Table of WM_ message names
  40. static const MAPID AllMessages[] = {
  41.    MSG( WM_CREATE )
  42.    MSG( WM_DESTROY )
  43.    MSG( WM_MOVE )
  44.    MSG( WM_SIZE )
  45.    MSG( WM_ACTIVATE )
  46.    MSG( WM_SETFOCUS )
  47.    MSG( WM_KILLFOCUS )
  48.    MSG( WM_ENABLE )
  49.    MSG( WM_SETREDRAW )
  50.    MSG( WM_SETTEXT )
  51.    MSG( WM_GETTEXT )
  52.    MSG( WM_GETTEXTLENGTH )
  53.    MSG( WM_PAINT )
  54.    MSG( WM_CLOSE )
  55.    MSG( WM_QUERYENDSESSION )
  56.    MSG( WM_QUIT )
  57.    MSG( WM_QUERYOPEN )
  58.    MSG( WM_ERASEBKGND )
  59.    MSG( WM_SYSCOLORCHANGE )
  60.    MSG( WM_ENDSESSION )
  61.    MSG( WM_SHOWWINDOW )
  62.    MSG( WM_CTLCOLORMSGBOX )
  63.    MSG( WM_CTLCOLOREDIT )
  64.    MSG( WM_CTLCOLORLISTBOX )
  65.    MSG( WM_CTLCOLORBTN )
  66.    MSG( WM_CTLCOLORDLG )
  67.    MSG( WM_CTLCOLORSCROLLBAR )
  68.    MSG( WM_CTLCOLORSTATIC )
  69.    MSG( WM_WININICHANGE )
  70.    MSG( WM_DEVMODECHANGE )
  71.    MSG( WM_ACTIVATEAPP )
  72.    MSG( WM_FONTCHANGE )
  73.    MSG( WM_TIMECHANGE )
  74.    MSG( WM_CANCELMODE )
  75.    MSG( WM_SETCURSOR )
  76.    MSG( WM_MOUSEACTIVATE )
  77.    MSG( WM_CHILDACTIVATE )
  78.    MSG( WM_QUEUESYNC )
  79.    MSG( WM_GETMINMAXINFO )
  80.    MSG( WM_ICONERASEBKGND )
  81.    MSG( WM_NEXTDLGCTL )
  82.    MSG( WM_SPOOLERSTATUS )
  83.    MSG( WM_DRAWITEM )
  84.    MSG( WM_MEASUREITEM )
  85.    MSG( WM_DELETEITEM )
  86.    MSG( WM_VKEYTOITEM )
  87.    MSG( WM_CHARTOITEM )
  88.    MSG( WM_SETFONT )
  89.    MSG( WM_GETFONT )
  90.    MSG( WM_QUERYDRAGICON )
  91.    MSG( WM_COMPAREITEM )
  92.    MSG( WM_COMPACTING )
  93.    MSG( WM_NCCREATE )
  94.    MSG( WM_NCDESTROY )
  95.    MSG( WM_NCCALCSIZE )
  96.    MSG( WM_NCHITTEST )
  97.    MSG( WM_NCPAINT )
  98.    MSG( WM_NCACTIVATE )
  99.    MSG( WM_GETDLGCODE )
  100.    MSG( WM_NCMOUSEMOVE )
  101.    MSG( WM_NCLBUTTONDOWN )
  102.    MSG( WM_NCLBUTTONUP )
  103.    MSG( WM_NCLBUTTONDBLCLK )
  104.    MSG( WM_NCRBUTTONDOWN )
  105.    MSG( WM_NCRBUTTONUP )
  106.    MSG( WM_NCRBUTTONDBLCLK )
  107.    MSG( WM_NCMBUTTONDOWN )
  108.    MSG( WM_NCMBUTTONUP )
  109.    MSG( WM_NCMBUTTONDBLCLK )
  110.    MSG( WM_KEYDOWN )
  111.    MSG( WM_KEYUP )
  112.    MSG( WM_CHAR )
  113.    MSG( WM_DEADCHAR )
  114.    MSG( WM_SYSKEYDOWN )
  115.    MSG( WM_SYSKEYUP )
  116.    MSG( WM_SYSCHAR )
  117.    MSG( WM_SYSDEADCHAR )
  118.    MSG( WM_KEYLAST )
  119.    MSG( WM_INITDIALOG )
  120.    MSG( WM_COMMAND )
  121.    MSG( WM_SYSCOMMAND )
  122.    MSG( WM_TIMER )
  123.    MSG( WM_HSCROLL )
  124.    MSG( WM_VSCROLL )
  125.    MSG( WM_INITMENU )
  126.    MSG( WM_INITMENUPOPUP )
  127.    MSG( WM_MENUSELECT )
  128.    MSG( WM_MENUCHAR )
  129.    MSG( WM_ENTERIDLE )
  130.    MSG( WM_MOUSEMOVE )
  131.    MSG( WM_LBUTTONDOWN )
  132.    MSG( WM_LBUTTONUP )
  133.    MSG( WM_LBUTTONDBLCLK )
  134.    MSG( WM_RBUTTONDOWN )
  135.    MSG( WM_RBUTTONUP )
  136.    MSG( WM_RBUTTONDBLCLK )
  137.    MSG( WM_MBUTTONDOWN )
  138.    MSG( WM_MBUTTONUP )
  139.    MSG( WM_MBUTTONDBLCLK )
  140.    MSG( WM_PARENTNOTIFY )
  141.    MSG( WM_MDICREATE )
  142.    MSG( WM_MDIDESTROY )
  143.    MSG( WM_MDIACTIVATE )
  144.    MSG( WM_MDIRESTORE )
  145.    MSG( WM_MDINEXT )
  146.    MSG( WM_MDIMAXIMIZE )
  147.    MSG( WM_MDITILE )
  148.    MSG( WM_MDICASCADE )
  149.    MSG( WM_MDIICONARRANGE )
  150.    MSG( WM_MDIGETACTIVE )
  151.    MSG( WM_MDISETMENU )
  152.    MSG( WM_CUT )
  153.    MSG( WM_COPY )
  154.    MSG( WM_PASTE )
  155.    MSG( WM_CLEAR )
  156.    MSG( WM_UNDO )
  157.    MSG( WM_RENDERFORMAT )
  158.    MSG( WM_RENDERALLFORMATS )
  159.    MSG( WM_DESTROYCLIPBOARD )
  160.    MSG( WM_DRAWCLIPBOARD )
  161.    MSG( WM_PAINTCLIPBOARD )
  162.    MSG( WM_VSCROLLCLIPBOARD )
  163.    MSG( WM_SIZECLIPBOARD )
  164.    MSG( WM_ASKCBFORMATNAME )
  165.    MSG( WM_CHANGECBCHAIN )
  166.    MSG( WM_HSCROLLCLIPBOARD )
  167.    MSG( WM_QUERYNEWPALETTE )
  168.    MSG( WM_PALETTEISCHANGING )
  169.    MSG( WM_PALETTECHANGED )
  170.    MSG( WM_DDE_INITIATE )
  171.    MSG( WM_DDE_TERMINATE )
  172.    MSG( WM_DDE_ADVISE )
  173.    MSG( WM_DDE_UNADVISE )
  174.    MSG( WM_DDE_ACK )
  175.    MSG( WM_DDE_DATA )
  176.    MSG( WM_DDE_REQUEST )
  177.    MSG( WM_DDE_POKE )
  178.    MSG( WM_DDE_EXECUTE )
  179.    MSG( WM_DROPFILES )
  180.    MSG( WM_POWER )
  181.    MSG( WM_WINDOWPOSCHANGED )
  182.    MSG( WM_WINDOWPOSCHANGING )
  183.  
  184. // MFC specific messages
  185.    MFCMSG( WM_QUERYAFXWNDPROC)
  186.    MFCMSG( WM_SIZEPARENT)
  187.    MFCMSG( WM_SETMESSAGESTRING)
  188.    MFCMSG( WM_IDLEUPDATECMDUI)
  189.    MFCMSG( WM_INITIALUPDATE)
  190.    MFCMSG( WM_COMMANDHELP)
  191.    MFCMSG( WM_HELPHITTEST)
  192.    MFCMSG( WM_EXITHELPMODE)
  193.    MFCMSG( WM_RECALCPARENT)
  194.    MFCMSG( WM_SIZECHILD)
  195.    MFCMSG( WM_KICKIDLE)
  196.    MFCMSG( WM_QUERYCENTERWND)
  197.    MFCMSG( WM_DISABLEMODAL)
  198.    MFCMSG( WM_FLOATSTATUS)
  199.    MFCMSG( WM_ACTIVATETOPLEVEL)
  200.    MFCMSG( WM_QUERY3DCONTROLS)
  201.    MFCMSG( WM_SOCKET_NOTIFY)
  202.    MFCMSG( WM_SOCKET_DEAD)
  203.  
  204.    { 0, NULL, }    // end of message list
  205. };
  206.  
  207. // Table of common MFC command IDs
  208. static const BASED_CODE MAPID AllCommands[] = {
  209.    MSG( ID_FILE_NEW )
  210.    MSG( ID_FILE_OPEN )
  211.    MSG( ID_FILE_CLOSE )
  212.    MSG( ID_FILE_SAVE )
  213.    MSG( ID_FILE_SAVE_AS )
  214.    MSG( ID_FILE_PAGE_SETUP )
  215.    MSG( ID_FILE_PRINT_SETUP )
  216.    MSG( ID_FILE_PRINT )
  217.    MSG( ID_FILE_PRINT_PREVIEW )
  218.    MSG( ID_FILE_UPDATE )
  219.    MSG( ID_FILE_SAVE_COPY_AS )
  220.    MSG( ID_FILE_SEND_MAIL )
  221.    MSG( ID_FILE_MRU_FIRST )
  222.    MSG( ID_FILE_MRU_FILE1 )
  223.    MSG( ID_FILE_MRU_FILE2 )
  224.    MSG( ID_FILE_MRU_FILE3 )
  225.    MSG( ID_FILE_MRU_FILE4 )
  226.    MSG( ID_FILE_MRU_FILE5 )
  227.    MSG( ID_FILE_MRU_FILE6 )
  228.    MSG( ID_FILE_MRU_FILE7 )
  229.    MSG( ID_FILE_MRU_FILE8 )
  230.    MSG( ID_FILE_MRU_FILE9 )
  231.    MSG( ID_FILE_MRU_FILE10 )
  232.    MSG( ID_FILE_MRU_FILE11 )
  233.    MSG( ID_FILE_MRU_FILE12 )
  234.    MSG( ID_FILE_MRU_FILE13 )
  235.    MSG( ID_FILE_MRU_FILE14 )
  236.    MSG( ID_FILE_MRU_FILE15 )
  237.    MSG( ID_FILE_MRU_FILE16 )
  238.    MSG( ID_FILE_MRU_LAST )
  239.    MSG( ID_EDIT_CLEAR )
  240.    MSG( ID_EDIT_CLEAR_ALL )
  241.    MSG( ID_EDIT_COPY )
  242.    MSG( ID_EDIT_CUT )
  243.    MSG( ID_EDIT_FIND )
  244.    MSG( ID_EDIT_PASTE )
  245.    MSG( ID_EDIT_PASTE_LINK )
  246.    MSG( ID_EDIT_PASTE_SPECIAL )
  247.    MSG( ID_EDIT_REPEAT )
  248.    MSG( ID_EDIT_REPLACE )
  249.    MSG( ID_EDIT_SELECT_ALL )
  250.    MSG( ID_EDIT_UNDO )
  251.    MSG( ID_EDIT_REDO )
  252.    MSG( ID_VIEW_TOOLBAR )
  253.    MSG( ID_VIEW_STATUS_BAR )
  254.    MSG( ID_APP_ABOUT )
  255.    MSG( ID_APP_EXIT )
  256.    MSG( ID_WINDOW_NEW )
  257.    MSG( ID_WINDOW_ARRANGE )
  258.    MSG( ID_WINDOW_CASCADE )
  259.    MSG( ID_WINDOW_TILE_HORZ )
  260.    MSG( ID_WINDOW_TILE_VERT )
  261.    MSG( ID_WINDOW_SPLIT )
  262.    MSG( ID_INDICATOR_EXT )
  263.    MSG( ID_INDICATOR_CAPS )
  264.    MSG( ID_INDICATOR_NUM )
  265.    MSG( ID_INDICATOR_SCRL )
  266.    MSG( ID_INDICATOR_OVR )
  267.    MSG( ID_INDICATOR_REC )
  268.    MSG( ID_INDICATOR_KANA )
  269.    MSG( AFX_IDW_CONTROLBAR_FIRST )
  270.    MSG( AFX_IDW_CONTROLBAR_LAST )
  271.    MSG( AFX_IDW_TOOLBAR )
  272.    MSG( AFX_IDW_STATUS_BAR )
  273.    MSG( AFX_IDW_PREVIEW_BAR )
  274.    MSG( AFX_IDW_RESIZE_BAR )
  275.    MSG( AFX_IDW_DOCKBAR_TOP )
  276.    MSG( AFX_IDW_DOCKBAR_LEFT )
  277.    MSG( AFX_IDW_DOCKBAR_RIGHT )
  278.    MSG( AFX_IDW_DOCKBAR_BOTTOM )
  279.    MSG( AFX_IDW_DOCKBAR_FLOAT )
  280.    MSG( AFX_IDW_PANE_FIRST )
  281.    MSG( AFX_IDW_PANE_LAST )
  282.    MSG( AFX_IDW_HSCROLL_FIRST )
  283.    MSG( AFX_IDW_VSCROLL_FIRST )
  284.    MSG( AFX_IDW_SIZE_BOX )
  285.    MSG( AFX_IDW_PANE_SAVE )
  286.    MSG( ID_HELP_INDEX )
  287.    MSG( ID_HELP_USING )
  288.    MSG( ID_CONTEXT_HELP )
  289.    MSG( ID_HELP )
  290.    MSG( ID_DEFAULT_HELP )
  291.    MSG( ID_NEXT_PANE )
  292.    MSG( ID_PREV_PANE )
  293.    MSG( ID_OLE_INSERT_NEW )
  294.    MSG( ID_OLE_EDIT_LINKS )
  295.    MSG( ID_OLE_EDIT_CONVERT )
  296.    MSG( ID_OLE_EDIT_CHANGE_ICON )
  297.    MSG( ID_OLE_EDIT_PROPERTIES )
  298.    MSG( ID_OLE_VERB_FIRST )
  299.    MSG( ID_OLE_VERB_LAST )
  300.    MSG( AFX_ID_PREVIEW_CLOSE )
  301.    MSG( AFX_ID_PREVIEW_NUMPAGE )
  302.    MSG( AFX_ID_PREVIEW_NEXT )
  303.    MSG( AFX_ID_PREVIEW_PREV )
  304.    MSG( AFX_ID_PREVIEW_PRINT )
  305.    MSG( AFX_ID_PREVIEW_ZOOMIN )
  306.    MSG( AFX_ID_PREVIEW_ZOOMOUT )
  307.    MSG( ID_RECORD_FIRST )
  308.    MSG( ID_RECORD_LAST )
  309.    MSG( ID_RECORD_NEXT )
  310.    MSG( ID_RECORD_PREV )
  311.  
  312.    // CMDLEARN's IDs
  313.    APPMSG( ID_UPDATE_STATUS )
  314.    APPMSG( ID_VIEW_COMBO_DIALOG )
  315.    APPMSG( ID_TRACE_MSG )
  316.    APPMSG( ID_TRACE_CMD )
  317.  
  318.    { 0, NULL }
  319. };
  320.  
  321. CMsgTracer::CMsgTracer()
  322. {
  323.    ASSERT(this==&theTracer);  // only one global object allowed
  324.  
  325.    m_szIndent[0]= 0;
  326.    m_nCallDepth = 0;
  327.    m_bTraceCmd=TRUE; 
  328.    m_bTraceMsg=TRUE; 
  329.  
  330.    // Initialize WM_ message name table
  331.    for (const MAPID* lpMM = AllMessages; lpMM->nID != 0; lpMM++) 
  332.       m_mapMsg[lpMM->nID] = (void*)lpMM->lpszName;
  333.  
  334.    // Initialize ID_ command name table
  335.    for (lpMM = AllCommands; lpMM->nID; lpMM++)
  336.       m_mapCmd[lpMM->nID] = (void*)lpMM->lpszName;
  337.  
  338.    // open trace file
  339.    TRY {
  340.       m_file.Open("TRACE.OUT", 
  341.          CFile::modeWrite | CFile::modeCreate | CFile::shareDenyWrite);
  342.    } CATCH_ALL(e) {
  343.       MessageBox(NULL, "Failed to open trace file.", NULL, 
  344.          MB_OK|MB_ICONEXCLAMATION);
  345.       MessageBeep(MB_ICONEXCLAMATION);
  346.    } END_CATCH_ALL
  347. }
  348.  
  349. CMsgTracer::~CMsgTracer()
  350. {
  351.    m_file.Close();         // write to disk
  352. }
  353.  
  354. //////////////////
  355. // Write string to trace file
  356. //
  357. void CMsgTracer::Write(LPCSTR buf, int len)
  358. {
  359.    if (m_file.m_hFile)
  360.       m_file.Write(buf, len >= 0 ? len : strlen(buf));
  361. }
  362.  
  363. //////////////////
  364. // Trace OnCmdMsg. Returns FALSE if not traced.
  365. //
  366. BOOL CMsgTracer::TRACE_OnCmdMsg(CCmdTarget* pTarg, UINT nID, int nCode, 
  367.    void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
  368. {
  369.    if (!m_bTraceCmd)
  370.       return FALSE;
  371.  
  372.    // print pExtra or "NULL"
  373.    char p1[20] = "NULL";
  374.    if (pExtra)
  375.       sprintf(p1,"0x%p", pExtra);
  376.  
  377.    // print pHandlerInfo or "NULL"
  378.    char p2[20] = "NULL";
  379.    if (pHandlerInfo)
  380.       sprintf(p2,"0x%p", pHandlerInfo);
  381.  
  382.    // Write diagnostic
  383.    char buf[255];
  384.    int len = sprintf(buf, 
  385.       "%s%s[%p]::OnCmdMsg(%s, %s, %s, %s)\n", 
  386.       m_szIndent,
  387.       pTarg->GetRuntimeClass()->m_lpszClassName, pTarg,
  388.       GetCommandName(nID),
  389.       GetCmdCodeName(nCode), 
  390.       p1, 
  391.       p2);
  392.    Write(buf, len);
  393.  
  394.    PushCallLevel();  // increment indent for pretty-printing
  395.    return TRUE;      // message traced
  396. }
  397.  
  398. // Don't show these messages, they clutter the file
  399. static UINT SkipMessages[] = {
  400.    WM_MOUSEMOVE,
  401.    WM_NCMOUSEMOVE,
  402.    WM_NCHITTEST,
  403.    WM_SETCURSOR,
  404.    WM_CTLCOLOR,
  405.    WM_ENTERIDLE,
  406.    WM_CANCELMODE,
  407.    0   // end of table
  408. };
  409.  
  410. //////////////////
  411. // Trace a WindowProc message. Returns FALSE if not traced.
  412. //
  413. BOOL CMsgTracer::TRACE_WindowProc(CWnd* pWnd, UINT msg, WPARAM wp, LPARAM lp)
  414. {
  415.    if (msg==WM_NCCREATE || msg==WM_NCDESTROY) { 
  416.       // Always note window creation/destruction
  417.       char buf[80];
  418.       int len = sprintf(buf,
  419.          "%s*** %s %s at %p ***\n",
  420.          m_szIndent, 
  421.          msg==WM_NCCREATE ? "Created" : "Destroyed",
  422.          pWnd->GetRuntimeClass()->m_lpszClassName, 
  423.          pWnd);
  424.       Write (buf, len);
  425.    }
  426.  
  427.    // Only trace of tracing is on.
  428.    if (!(m_bTraceMsg || 
  429.       (m_bTraceCmd && 
  430.          (msg==WM_COMMAND || msg==WM_NOTIFY || msg==WM_IDLEUPDATECMDUI))))
  431.       return FALSE;
  432.  
  433.    // Don't report frequently sent messages
  434.    for (UINT* lpMessage = SkipMessages; *lpMessage != 0; lpMessage++) {
  435.       if (*lpMessage == msg) 
  436.          return FALSE;
  437.    }
  438.  
  439.    // Write diagnostic message
  440.    char buf[255];
  441.    int len = sprintf(buf, 
  442.       "%s%s[%p]::WindowProc(%s, 0x%04x, 0x%08lx)\n", 
  443.       m_szIndent,
  444.       pWnd->GetRuntimeClass()->m_lpszClassName, 
  445.       pWnd,
  446.       GetMessageName(msg), 
  447.       wp, 
  448.       lp);
  449.    Write(buf, len);
  450.  
  451.    PushCallLevel();        // increment indent for pretty-printing
  452.    return TRUE;            // message traced
  453. }
  454.  
  455. //////////////////
  456. // Trace OnCommand. Returns FALSE if not traced.
  457. //
  458. BOOL CMsgTracer::TRACE_OnCommand(CWnd* pWnd, WPARAM wp, LPARAM lp)
  459. {
  460.    if (!m_bTraceCmd)
  461.       return FALSE;
  462.  
  463.    // Write diagnostic message
  464.    char buf[255];
  465.    int len = sprintf(buf, 
  466.       "%s%s[%p]::OnCommand(%s, 0x%08lx)\n", 
  467.       m_szIndent,
  468.       pWnd->GetRuntimeClass()->m_lpszClassName, 
  469.       pWnd, 
  470.       GetCommandName(wp), 
  471.       lp);
  472.    Write(buf, len);
  473.  
  474.    PushCallLevel();        // increment indent for pretty-printing
  475.    return TRUE;            // traced
  476. }
  477.  
  478. /////////////////
  479. // Trace return value from OnCmdMsg, OnCommand or WindowProc.
  480. //
  481. void CMsgTracer::TRACE_ReturnOnCmdMsg(BOOL bRet)
  482. {
  483.    PopCallLevel();
  484.    char buf[80];
  485.    int len = sprintf(buf, "%s%s\n", m_szIndent, bRet ? "TRUE" : "FALSE");
  486.    Write(buf, len);
  487. }
  488.  
  489. void CMsgTracer::TRACE_ReturnOnCommand(BOOL bRet)
  490. {
  491.    PopCallLevel();
  492.    char buf[80];
  493.    int len = sprintf(buf, "%s%s\n", m_szIndent, bRet ? "TRUE" : "FALSE");
  494.    Write(buf, len);
  495. }
  496.  
  497. void CMsgTracer::TRACE_ReturnWindowProc(LRESULT lRet)
  498. {
  499.    PopCallLevel();
  500.    char buf[80];
  501.    int len = sprintf(buf, "%s0x%08x\n", m_szIndent, lRet);
  502.    Write(buf, len);
  503. }
  504.  
  505. ////////////////
  506. // Get message name from ID.
  507. //
  508. LPCSTR CMsgTracer::GetMessageName(UINT msg)
  509. {
  510.    // Use MFC map to improve performance looking up
  511.    // (hash is faster than linear search).
  512.    //
  513.    static char szBuf[80];        // scratch buffer
  514.  
  515.    if (msg >= 0xC000) {
  516.       // Window message registered with 'RegisterWindowMessage'
  517.       // (actually a USER atom)
  518.       if (::GetClipboardFormatName(msg, szBuf, sizeof(szBuf)) != 0)
  519.          return szBuf;
  520.  
  521.    } else if (msg >= WM_USER) {
  522.       // WM_USER + x message
  523.       sprintf(szBuf, "WM_USER+0x%04x", msg - WM_USER);
  524.       return szBuf;
  525.  
  526.    }
  527.  
  528.    // Look in name table
  529.    LPCSTR lpsz = (LPCSTR)m_mapMsg[msg];
  530.    if (lpsz)
  531.       return lpsz;
  532.  
  533.    // Unnamed message ID
  534.    sprintf(szBuf, "0x%04x", msg);
  535.    return szBuf;
  536. }
  537.  
  538. //////////////////
  539. // Get command name from ID
  540. //
  541. LPCSTR CMsgTracer::GetCommandName(UINT nID)
  542. {
  543.    // find message name
  544.    if (nID >= 0x8000) {
  545.       LPCSTR lpsz = (LPCSTR)m_mapCmd[nID];
  546.       if (lpsz)
  547.          return lpsz;
  548.    }
  549.    static char szBuf[80];
  550.    sprintf(szBuf, "%d", nID);
  551.    return szBuf;
  552. }
  553.  
  554. //////////////////
  555. // Get command code name (CN_COMMAND, etc) from ID.
  556. //
  557. LPCSTR CMsgTracer::GetCmdCodeName(int nCode)
  558. {
  559.    if (nCode==CN_COMMAND)
  560.       return "CN_COMMAND";
  561.    else if (nCode==CN_UPDATE_COMMAND_UI)
  562.       return "CN_UPDATE_COMMAND_UI";
  563.  
  564.    static char szBuf[80];
  565.    sprintf(szBuf, "%d", nCode);
  566.    return szBuf;
  567. }
  568.  
  569. //////////////////
  570. // Handle Trace On/Off (messages)
  571. //
  572. void CMsgTracer::OnTraceMsg()    
  573.    m_bTraceMsg = !m_bTraceMsg;
  574.    char buf[80];
  575.    int len = sprintf(buf, "MESSAGE TRACING %s\n", m_bTraceMsg ? "ON" : "OFF");
  576.    Write(buf, len);
  577. }
  578.  
  579. //////////////////
  580. // Handle Trace On/Off (commands)
  581. //
  582. void CMsgTracer::OnTraceCmd()    
  583.    m_bTraceCmd = !m_bTraceCmd; 
  584.    char buf[80];
  585.    int len = sprintf(buf, "COMMAND TRACING %s\n", m_bTraceCmd ? "ON" : "OFF");
  586.    Write(buf, len);
  587. }
  588.  
  589. void CMsgTracer::OnUpdateTraceMsg(CCmdUI* pCmdUI)
  590.    pCmdUI->SetCheck(m_bTraceMsg); 
  591. }
  592.  
  593. void CMsgTracer::OnUpdateTraceCmd(CCmdUI* pCmdUI)
  594. {
  595.    pCmdUI->SetCheck(m_bTraceCmd); 
  596. }
  597.  
  598. #endif
  599.